package com.benmei.weike.service.weixin;

import com.benmei.weike.dao.weixin.WeixinEventPushArticleDao;
import com.benmei.weike.dao.weixin.WeixinEventPushDao;
import com.benmei.weike.dao.weixin.WeixinScanLogDao;
import com.benmei.weike.dao.weixin.WeixinSubscribeLogDao;
import com.benmei.weike.entity.weixin.*;
import com.benmei.weike.util.JsonUtil;
import com.benmei.weike.util.XmlUtil;
import com.benmei.weike.web.vo.weixin.Event;
import com.benmei.weike.web.vo.weixin.MsgType;
import com.benmei.weike.web.vo.weixin.WeixinMessage;
import com.benmei.weike.web.vo.weixin.response.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * 微信Message 处理service、 处理微信具体的消息
 *
 * @author Peter
 */
@Component
public class WeixinMessageProcessService {


    /**
     * 10000+实景案例
     */
    private static final String V1002_SJAL = "V1002_SJAL";

    /**
     * 在线客服小好 eventkey
     */
    private static final String V1001_KEFU = "V1001_KEFU";

    private static Logger logger = LoggerFactory.getLogger(WeixinMessageProcessService.class);

    @Autowired
    private WeixinEventPushDao weixinEventPushDao;

    @Autowired
    private WeixinEventPushArticleDao weixinEventPushArticleDao;

    @Autowired
    private WeixinSubscribeLogDao weixinSubscribeLogDao;

    @Autowired
    private WeixinScanLogDao weixinScanLogDao;

    @Autowired
    private WeixinKeyReplyService weixinKeyReplyService;

    @Autowired
    private WeixinConf weixinConf;

    // ========= 基本消息处理 ==============================

    /**
     * 文本消息:消息转发到多客服
     * <p>
     * <pro>
     * <p>
     * <xml> <ToUserName><![CDATA[touser]]></ToUserName>
     * <FromUserName><![CDATA[fromuser]]></FromUserName>
     * <CreateTime>1399197672</CreateTime>
     * <MsgType><![CDATA[transfer_customer_service]]></MsgType> </xml>
     * <p>
     * </pro>
     *
     * @param msg
     */
    public String processTextMsg(WeixinMessage msg) {
        String reponseXml = "";
        logger.info("文本消息:如果包含关键字，回复关键字对应的内容，否则转发到客服");
        String key = msg.getContent().trim();
        // 1. 回复关键字
        WeixinKeyReply weixinKeyReply = weixinKeyReplyService.searchByKey(key);
        if (weixinKeyReply != null) {
            logger.info("\n回复关键字对应的内容：key=" + key + ", replayRecord=" + JsonUtil.toJson(weixinKeyReply));
            if (MsgType.text.name().equals(weixinKeyReply.getMsgType())) {
                reponseXml = XmlUtil.toXml(createTextMsg(msg, weixinKeyReply.getContent()));
            } else if (MsgType.image.name().equals(weixinKeyReply.getMsgType())) {
                reponseXml = XmlUtil.toXml(createImageMsg(msg, weixinKeyReply.getMediaId()));
            }
        } else {
            // 2. 转发到客服
            logger.info("\n转发到客服,key=" + key);
            BaseMessage result = new BaseMessage();
            result.setCreateTime(msg.getCreateTime());
            result.setFromUserName(msg.getToUserName());
            result.setMsgType("transfer_customer_service");
            result.setToUserName(msg.getFromUserName());
            reponseXml = XmlUtil.toXml(result);
        }
        return reponseXml;
    }

    private ImageMessage createImageMsg(WeixinMessage msg, String mediaId) {
        ImageMessage message = new ImageMessage();
        message.setCreateTime(msg.getCreateTime());
        message.setFromUserName(msg.getToUserName());
        message.setMsgType(MsgType.image.name());
        message.setToUserName(msg.getFromUserName());
        message.getImage().setMediaId(mediaId);
        return message;
    }

    // ========= 事件处理 ===================================

    // 用户订阅时自动回复的消息
    private String createSubscribeMsg(WeixinMessage msg) {
        WeixinSubscribeLog log = new WeixinSubscribeLog();
        log.setCreateDate(new Date());
        log.setEvent(Event.subscribe.name());
        log.setOpenid(msg.getFromUserName());
        weixinSubscribeLogDao.save(log);

        String reponseXml = "";

        String content = "Hi,来到外教君，你一定有远大的目标！\n" +
                "在这里提高英语听力和口语，为自己的未来做规划，你只需要一个手机，一副耳机，每天50分钟，\n" +
                "怎么学，怎么进步，我们已为你准备好！\n" +
                "\n" +
                "\ue231 <a href=\"http://tpo.waijiaojun.com/tpo/buy.html\">托福听力提分TPO神器</a>" +
                "\n\n" +
                "有疑问？每天9:00 - 24:00，添加我们客服【回复1】";
        String xmlStr = "<xml>\n" +
                "    <ToUserName><![CDATA[" + msg.getFromUserName() + "]]></ToUserName>\n" +
                "    <FromUserName><![CDATA[" + msg.getToUserName() + "]]></FromUserName>\n" +
                "    <CreateTime>" + msg.getCreateTime() + "</CreateTime>\n" +
                "    <MsgType><![CDATA[text]]></MsgType>\n" +
                "    <Content><![CDATA[" + content + "]]></Content>\n" +
                "</xml>\n";
        return xmlStr;
    }

    private TextMessage createTextMsg(WeixinMessage msg, String content) {
        TextMessage textMessage = new TextMessage();
        textMessage.setCreateTime(msg.getCreateTime());
        textMessage.setFromUserName(msg.getToUserName());
        textMessage.setMsgType(MsgType.text.name());
        textMessage.setToUserName(msg.getFromUserName());
        textMessage.setContent(content);
        return textMessage;
    }

    /**
     * 普通订阅事件
     *
     * @param msg
     */
    public String processSubscribeMsg(WeixinMessage msg) {
        logger.info("普通订阅事件，注册账号");
        // 直接关注微信公众号（普通订阅） 注册账号

        // return createSubscribeMsg(msg);
        return createSubscribeMsg(msg);
    }

    /**
     * 订阅事件:扫描带参数二维码事件，用户未关注时，进行关注后的事件推送
     * <p>
     * 提示：1.成功成为XX的下线； 2.已经是XXX的下线了。
     *
     * @param msg
     * @throws
     */
    public String processScanForSubscribe(WeixinMessage msg) {
        logger.info("订阅事件:扫描带参数二维码事件，用户未关注时，进行关注后的事件推送");

        String openid = msg.getFromUserName();

        // 分享微信公众号获取积分qrscene_
        saveScanLog(msg, "未关注 扫描二维码");

        return createSubscribeMsg(msg);
    }

    /**
     * 扫描带参数二维码事件:用户已关注时的事件推送
     *
     * @param msg
     */
    public String processScan(WeixinMessage msg) {
        // ToUserName 开发者微信号
        // FromUserName 发送方帐号（一个OpenID）
        // CreateTime 消息创建时间 （整型）
        // MsgType 消息类型，event
        // Event 事件类型，SCAN
        // EventKey 事件KEY值，是一个32位无符号整数，即创建二维码时的二维码scene_id
        // Ticket 二维码的ticket，可用来换取二维码图片
        logger.info("扫描带参数二维码事件:用户已关注时的事件推送");

        // 分享微信公众号获取积分qrscene_
        saveScanLog(msg, "已关注 扫描二维码");

        return createSubscribeMsg(msg);
    }

    private void saveScanLog(WeixinMessage msg, String caseName) {
        String str = msg.getEventKey().replace("qrscene_", "");

        WeixinScanLog log = new WeixinScanLog();
        log.setCaseCode("subscribed");
        log.setCaseName(caseName);
        log.setCreateDate(new Date());
        log.setOpenid(msg.getFromUserName());
        log.setParentSceneStr(str);
        log.setSceneStr(str);
        log.setUpdateDate(new Date());
        log.setWeixinPublicId(weixinConf.getPublicId());

        weixinScanLogDao.save(log);
    }

    /**
     * 点击菜单事件
     *
     * @param msg
     */
    public String processClick(WeixinMessage msg) {
        logger.info("点击菜单事件");
        String reponseXml = "";
        if (V1001_KEFU.equals(msg.getEventKey())) {

        } else if (V1002_SJAL.equals(msg.getEventKey())) {

        }
        return reponseXml;
    }

    /**
     * 创建图文消息
     *
     * @param msg
     * @param eventType 事件类型
     * @param eventKey  事件key
     * @return
     */
    private NewsMessage createNews(WeixinMessage msg, String eventType, String eventKey) {
        NewsMessage news = new NewsMessage();
        news.setCreateTime(msg.getCreateTime());
        news.setFromUserName(msg.getToUserName());
        news.setMsgType(MsgType.news.name());
        news.setToUserName(msg.getFromUserName());

        WeixinEventPush wixinEventPush = weixinEventPushDao.findEventCode(eventType, eventKey);
        if (wixinEventPush != null) {
            List<WeixinEventPushArticle> articleList = weixinEventPushArticleDao.findByEvnetCode(wixinEventPush.getEventCode());
            if (articleList != null) {
                news.setArticleCount(articleList.size());
                for (WeixinEventPushArticle arc : articleList) {
                    Article a = new Article();
                    a.setDescription(arc.getDescription());
                    a.setTitle(arc.getTitle());
                    a.setPicUrl(arc.getPicUrl());
                    a.setUrl(arc.getUrl());
                    news.getItem().getItems().add(a);
                }
            }
        }
        return news;
    }

    /**
     * 取消订阅
     *
     * @param msg
     */
    public void processUnsubscribe(WeixinMessage msg) {
        WeixinSubscribeLog log = new WeixinSubscribeLog();
        log.setCreateDate(new Date());
        log.setEvent(Event.unsubscribe.name());
        log.setOpenid(msg.getFromUserName());
        weixinSubscribeLogDao.save(log);

    }

}
